package com.gitee.wsl.net

import com.gitee.wsl.security.hash.md5
import io.ktor.http.Url
import io.ktor.util.toMap
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder


fun Url.hash() = toString().md5().hashCode()

fun Url.matches(other: Url): Boolean {
    return rawSegments.size == other.rawSegments.size
            && rawSegments.mapIndexed { index, pathSegment ->
        when {
            pathSegment == "*" -> true
            pathSegment.endsWith("*") -> other.rawSegments.getOrNull(index)
                ?.startsWith(pathSegment.dropLast(1)) == true

            else -> pathSegment == other.rawSegments.getOrNull(index)
        }
    }.all { it }
            && parameters.toMap().all {
        if (it.value.size == 1 && it.value.first() == "*") true
        else it.value == other.parameters.getAll(it.key)
    }
}

object UrlSerializer : KSerializer<Url> {
    override val descriptor = PrimitiveSerialDescriptor("Url", PrimitiveKind.STRING)
    override fun deserialize(decoder: Decoder) = Url(decoder.decodeString())
    override fun serialize(encoder: Encoder, value: Url) = encoder.encodeString(value.toString())
}

typealias SerializableUrl = @Serializable(with = UrlSerializer::class) Url